package com.rfid.api;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import cn.pda.serialport.SerialPort;
import com.rfid.reader.PCReader;
import com.rfid.spec.NetDataReport;
import com.rfid.spec.SpecInvenParamSet;
import com.rfid.spec.SpecOutputRecord;
import com.rfid.spec.TagDataReport;
import com.rfid.spec.TagOperateHandle;
import com.rfid.spec.tagaccess.SpecOutputSet;
import com.rfid.transport.SerialPortFinder;
import com.rfid.transport.Transport_Hid;
import com.rfid.transport.Transport_Ztek;
import com.urovo.hf.HfSwitchLib;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;

public class PCReaderInterface
{
  private PCReader m_reader = null;
  private boolean isOpen = false;
  public PCReader GetReader() { return this.m_reader; }
  public static String[] GetSerialPortPath() {
    return new SerialPortFinder().getAllDevicesPath();
  }
  public int PC_Open(String conStr) {
    ConfigStrParser m_cfg = new ConfigStrParser();
    if (!m_cfg.Parse(conStr))
    {
      return -3;
    }
    StringBuffer readerStr = new StringBuffer();
    if (!m_cfg.ParseByName("RDType", readerStr))
    {
      return -3;
    }
    StringBuffer commType = new StringBuffer();
    if (!m_cfg.ParseByName("CommType", commType))
    {
      return -3;
    }
    String commTypeStr = commType.toString();
    int iret = -1;
    this.m_reader = PCReader.create(readerStr.toString(), commTypeStr);
    if (this.m_reader == null)
    {
      return -3;
    }

    iret = this.m_reader.Init();
    if (iret != 0)
    {
      return iret;
    }



    if (commTypeStr.equals("BLUETOOTH")) {

      StringBuffer addrStr = new StringBuffer();
      if (!m_cfg.ParseByName("Addr", addrStr)) {

        StringBuffer nameBuffer = new StringBuffer();
        if (!m_cfg.ParseByName("Name", nameBuffer)) {

          this.m_reader = null;
          return -3;
        }

        ArrayList<BluetoothCfg> m_blueList = GetPairBluetooth();
        boolean b_nameOk = false;
        for (BluetoothCfg bluetoolCfg : m_blueList) {

          if (bluetoolCfg.GetName().equals(nameBuffer.toString())) {

            b_nameOk = true;
            addrStr.append(bluetoolCfg.GetAddr());
            break;
          }
        }
        if (!b_nameOk) {

          this.m_reader = null;
          return -3;
        }
      }
      iret = this.m_reader.OpenBlueTooth(addrStr.toString());
      if (iret != 0)
      {
        return iret;
      }
    } else if (commTypeStr.equals("NET")) {
      StringBuffer sRemoteIp = new StringBuffer();
      StringBuffer sRemotePort = new StringBuffer();
      if (!m_cfg.ParseByName("RemoteIp", sRemoteIp))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("RemotePort", sRemotePort))
      {
        return -3;
      }

      int remotePort = Integer.parseInt(sRemotePort.toString());
      iret = this.m_reader.OpenNet(sRemoteIp.toString(), remotePort);
      if (iret != 0)
      {
        return iret;
      }
    }
    else if (commTypeStr.equals("COM")) {
      StringBuffer sPath = new StringBuffer();
      StringBuffer sBand = new StringBuffer();
      StringBuffer sFrame = new StringBuffer();
      StringBuffer sAddr = new StringBuffer();

      if (!m_cfg.ParseByName("ComPath", sPath))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("Baund", sBand))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("Frame", sFrame))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("Addr", sAddr))
      {
        return -3;
      }
      int mBaund = Integer.parseInt(sBand.toString());
      int mAddr = Integer.parseInt(sAddr.toString()) & 0xFF;
      iret = this.m_reader.OpenCom(sPath.toString(), mBaund, sFrame.toString(),
              (byte)mAddr);
      if (iret != 0)
      {
        return iret;
      }
    } else if (commTypeStr.equals("USB")) {
      StringBuffer usbDes = new StringBuffer();
      if (!m_cfg.ParseByName("Description", usbDes))
      {
        usbDes.append("");
      }

      iret = this.m_reader.OpenHid(usbDes.toString());
      if (iret != 0)
      {
        return iret;
      }
    } else if (commTypeStr.equals("Z-TEK")) {
      StringBuffer sPort = new StringBuffer();

      StringBuffer sBand = new StringBuffer();
      StringBuffer sFrame = new StringBuffer();
      StringBuffer sAddr = new StringBuffer();

      if (!m_cfg.ParseByName("Port", sPort))
      {
        return -3;
      }

      if (!m_cfg.ParseByName("Baund", sBand))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("Frame", sFrame))
      {
        return -3;
      }
      if (!m_cfg.ParseByName("Addr", sAddr))
      {
        return -3;
      }
      int mPort = Integer.parseInt(sPort.toString());
      int mBaund = Integer.parseInt(sBand.toString());
      int mAddr = Integer.parseInt(sAddr.toString()) & 0xFF;
      iret = this.m_reader.OpenZTEK(mPort, mBaund, sFrame.toString(),
              (byte)mAddr);
      if (iret != 0)
      {
        return iret;
      }
    }
    else {
      return -3;
    }
    int checkTime = 2;
    boolean b_online = false;
    for (int j = 0; j < checkTime; j++) {

      iret = this.m_reader.OnlineCheck();
      if (iret == 0) {

        b_online = true;

        break;
      }
      try {
        Thread.sleep(20L);
      }
      catch (InterruptedException interruptedException) {}
    }


    if (!b_online) {

      PC_Close();
      return iret;
    }
    this.isOpen = true;
    return iret;
  }



  public int PC_Close() {
    if (this.m_reader == null) {

      this.isOpen = false;
      return 0;
    }
    int iret = this.m_reader.Close();
    if (iret == 0) {

      this.m_reader = null;
      this.isOpen = false;
    }

    return iret;
  }
  public int PC_GetReaderInfo(StringBuffer buffer) { return this.m_reader.GetReaderInfor(buffer); }
  public int PC_TagInventory(byte AIType, byte[] AntennaIDs, int mTimeout, Object InvenParamSpecList) {
    if (this.m_reader == null)
    {
      return -3;
    }
    this.m_reader.ClearTDRManager();
    return this.m_reader.PICC_Inventory(AIType, AntennaIDs, mTimeout, (SpecInvenParamSet)InvenParamSpecList);
  }
  public int PC_GetTagReportCount() {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.GetTagReportCount();
  }

  public TagDataReport PC_GetTagDataReport(byte seek) {
    if (this.m_reader == null)
    {
      return null;//Integer.valueOf(-3);
    }
    return this.m_reader.GetTagDataReport(seek);
  }
  public static Object PC_CreateInvenParamSpecList() {
    return SpecInvenParamSet.Create();
  }
  public int PC_OpenRFTransmitter() {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.OpenRFTransmitter();
  }
  public int PC_OpenRFTransmitter(byte mAntID) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.OpenRFTransmitter(mAntID);
  }
  public int PC_CloseRFTransmitter() {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.CloseRFTransmitter();
  }
  public int PC_ResetCommuImmeTimeout() {
    if (this.m_reader == null)
    {
      return -1;
    }
    this.m_reader.m_trancQuickExit = false;
    return 0;
  }
  public int PC_SetCommuImmeTimeout() {
    if (this.m_reader == null) {
      return -1;
    }
    this.m_reader.m_trancQuickExit = true;
    return 0;
  }
  public int PC_SetRFPower(byte index) {
    if (this.m_reader == null) {
      return -1;
    }
    if (index >= 1 && index <= 6) {
      return this.m_reader.SetRFPower(index);
    }
    return 4;
  }
  public int PC_GetRFPower(Byte index) {
    if (this.m_reader == null) {
      return -1;
    }
    return this.m_reader.GetRFPower(index);
  }
  public int PC_GetOverflowTime(Integer mTime) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.GetOverflowTime(mTime);
  }
  public int PC_SetOverflowTime(int mTime) {
    if (this.m_reader == null)
    {
      return -1;
    }
    if (mTime < 0 && mTime > 255)
    {
      return -3;
    }
    return this.m_reader.SetOverflowTime(mTime);
  }
  public int PC_GetAntennaInterfaceCount() {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.GetAntennaInterfaceCount();
  }
  public int PC_SetAcessAntenna(byte AntennaID) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.SetAcessAntenna(AntennaID);
  }
  public int PC_ConfigBlockWrite(int cfgno, byte[] cfgdata, int nSize, int mask)
  {
    if (this.m_reader == null)
    {
      return -3;
    }
    return  this.m_reader.WriteConfigBlock(cfgno, cfgdata, nSize, mask);
  }
  public int PC_ConfigBlockRead(int cfgno,byte[] cfgdata)
  {
    if (this.m_reader == null)
    {
      return -3;
    }
    return  this.m_reader.ReadCfgBlock(cfgno,cfgdata);
  }
  public int PC_ConfigBlockSave(int cfgno)
  {
    if (this.m_reader == null)
    {
      return -3;
    }
    return  this.m_reader.SaveConfigBlock(cfgno);
  }
  /*
    网络
     */
  public  int PC_NetOpen()
  {
    int iret=-1;
    this.m_reader = PCReader.create("PC8001", "NET");
    if (this.m_reader == null)
    {
      return -3;
    }
    iret = this.m_reader.OpenNet("255.255.255.255", 6688);
    if (iret != 0)
    {
      return iret;
    }
    return iret;
  }
  public int PC_NetClose()
  {
    return PC_Close();
  }
  public int PC_NetInventory()
  {
    if (this.m_reader == null)
    {
      return -3;
    }
    this.m_reader.ClearNetManager();
    return this.m_reader.Net_Inventory();
  }
  public int PC_GetNetReportCount()
  {
    if (this.m_reader == null)
    {
      return -3;
    }
    return  this.m_reader.GetNetReportCount();
  }
  public NetDataReport PC_GetNetDataReport(byte seek)
  {
    if (this.m_reader == null)
    {
      return null;
    }
    return  this.m_reader.GetNetDataReport(seek);
  }
  public  int PC_SetNet(byte[] pIp,byte[] pMask,byte[] pGrateway){
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.SetNet(pIp,pMask,pGrateway);
  }


  public boolean IsReaderOpen() { return this.isOpen; }
  public static ArrayList<BluetoothCfg> GetPairBluetooth() {
    BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();
    if (_bluetooth == null)
    {
      return null;
    }
    ArrayList<BluetoothCfg> _bluetoolList = new ArrayList<BluetoothCfg>();
    Set<BluetoothDevice> m_list = _bluetooth.getBondedDevices();
    for (BluetoothDevice bluetoothDevice : m_list) {
      BluetoothCfg m_cfg = new BluetoothCfg();
      m_cfg.SetName(bluetoothDevice.getName());
      m_cfg.SetAddr(bluetoothDevice.getAddress());
      _bluetoolList.add(m_cfg);
    }
    return _bluetoolList;
  }
  public static int EnumerateUsb(Context context) { return Transport_Hid.ListUsbDevice(context); }
  public static int EnumerateZTEK(Context context, int vid, int pid) { return Transport_Ztek.ListUsbDevice(context, vid, pid); }
  public static String GetUsbDescription(int idx) { return Transport_Hid.GetUsbDescription(idx); }
  public static boolean HasUsbPermission(String usbDes) { return Transport_Hid.hasUsbPermission(usbDes); }
  public static boolean RequestUsbPermission(String usbDes) { return Transport_Hid.requestUsbPermission(usbDes); }
  public boolean PC_IsAirProtocolSupport(long aipId) { return this.m_reader.IsAirProtocolSupport(aipId); }
  public int PC_LoadFactoryDefault() { return this.m_reader.LoadFactoryDefault(); }
  /*************************************************暂时*************************************************/
  private static int deveceType = 0;
  private static void InitM201() {
    if (DEV_M201MicoInit()) {
      deveceType = 1;
      return;
    }
    DEV_M201Init();
    deveceType = 2;
  }
  private void UnIntM201() {
    if (deveceType == 1) {
      DEV_M201MicoUnInit();
    }
    else if (deveceType == 2) {
      DEV_M201UnInit();
    }
  }
  private static boolean DEV_M201MicoInit() { return (HfSwitchLib.hf_switch_init() == 0); }
  private static boolean DEV_M201MicoUnInit() { return (HfSwitchLib.hf_switch_exit() == 0); }
  private static void DEV_M201Init() {
    try {
      SerialPort serialPort = new SerialPort(13, 38400, 0);
      if (!serialPort.IsDevOK()) {
        return;
      }

      SerialPort.rfidPoweron();
      SerialPort.setGPIOhigh(143);
      serialPort.close(13);
    }
    catch (SecurityException e) {

      e.printStackTrace();
    }
    catch (IOException e) {

      e.printStackTrace();
    }
  }
  private static void DEV_M201UnInit() {
    SerialPort.setGPIOlow(143);
    SerialPort.rfidPoweroff();
  }
  /*
  public int GetReaderLastReturnError() {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.GetLastReaderErrCode();
  }

  public int GetPassingCounter(long[] inFlow, long[] outFlow) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.GetPassingCounter(inFlow, outFlow);
  }
  public int ResetPassingCounter(int flag) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.ResetPassingCounter(flag);
  }
  public int GetSysTime(StringBuffer strTime) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.GetSysTime(strTime);
  }
  public int SetSysTime(int year, int month, int day, int hour, int min, int sec) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.SetSysTime(year, month, day, hour, min, sec);
  }
  public int SetOutput(Object outputOpers) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.SetOutput((SpecOutputSet)outputOpers);
  }

  public int ReverseInOutDirection() {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.ReverseInOutDirection();
  }

  public int BuffMode_FetchRecords(byte flags) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.BuffMode_FetchRecords(flags);
  }
  public int BuffMode_ClearRecords() {
    if (this.m_reader == null) {
      return -1;
    }
    return this.m_reader.EmptyRAMRecord();
  }
  public int BuffMode_FlashEmpty() {
    if (this.m_reader == null) {
      return -1;
    }
    return this.m_reader.BuffMode_FlashEmpty();
  }

  public int GetSystemTime(int[] year, byte[] month, byte[] day, byte[] hour, byte[] minute, byte second) { return -7; }
  public int SetSystemTime(int year, int month, int day, int hour, int minute, int second) {
    return -3;
  }

   */
  public static int ParseTagDataReportRaw(Object hTagReport, byte[] rawBuffer, int[] nSize) {
    TagDataReport p = (TagDataReport)hTagReport;
    if (p == null)
    {
      return -3;
    }
    int nCopy = 0;
    if (rawBuffer != null) {

      nCopy = p.m_rawData.getBufferLen();
      if (nCopy > rawBuffer.length)
      {
        nCopy = rawBuffer.length;
      }
      System.arraycopy(p.m_rawData.GetBuffer(), 0, rawBuffer, 0, nCopy);
    }
    if (nSize != null)
    {
      nSize[0] = nCopy;
    }
    return 0;
  }
  public int DisconnectTag(TagOperateHandle hTag) {
    int iret = this.m_reader.PICC_DisConnect(hTag.getTagHandle());
    if (iret == 0)
    {
      hTag.setTagHandle(null);
    }
    return iret;
  }
  public boolean IsAirProtocolSupport(long aipId) { return this.m_reader.IsAirProtocolSupport(aipId); }
  public Object CreateSetOutputOperations() { return SpecOutputSet.create(); }
  public int AddOneOutputOperation(Object hOperas, byte outNo, byte outMode, int outFrequency, int outActiveDuration, int outInactiveDuration) {
    SpecOutputSet pSet = (SpecOutputSet)hOperas;
    if (pSet == null)
    {
      return -3;
    }
    SpecOutputRecord p = SpecOutputRecord.create();
    if (p == null)
    {
      return -6;
    }
    p.outputNum = outNo;
    p.outputMode = outMode;
    p.outputFrequency = outFrequency;
    p.outputActive = outActiveDuration;
    p.outputInactive = outInactiveDuration;

    pSet.AddOutputOperation(p);
    return 0;
  }

  public int SelectAuthKey(byte keyType) {
    if (this.m_reader == null)
    {
      return -1;
    }
    return this.m_reader.SelectAuthKey(keyType);
  }
  public static int SetInvenStopTrigger(Object hInvenParams, byte stopTriggerType, long maxTimeout, long triggerValue) {
    SpecInvenParamSet p = (SpecInvenParamSet)hInvenParams;
    if (p == null)
    {
      return -3;
    }
    p.m_StopTrigger.m_enable = true;
    p.m_StopTrigger.m_triggerType = stopTriggerType;
    p.m_StopTrigger.m_timeout = maxTimeout;
    p.m_StopTrigger.m_triggerValue = triggerValue;

    return 0;
  }

  public int Login(byte[] pwd) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.Login(pwd);
  }

  public int EnablePasswordLogin(byte[] pwd, boolean enable) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.EnablePasswordLogin(pwd, enable);
  }

  public int UpdateLoginPassword(byte[] pwd, byte[] newPwd) {
    if (this.m_reader == null) {
      return -3;
    }
    return this.m_reader.UpdateLoginPassword(pwd, newPwd);
  }
  public int DetectTags(int[] ant, byte[][] uid, boolean[] ret) {
    if (this.m_reader == null) {
      return -3;
    }
    return this.m_reader.DetectTags(ant, uid, ret);
  }


  public int DetectNoise(int[] voltage, int[] bufSize) {
    if (this.m_reader == null) {
      return -3;
    }
    return this.m_reader.DetectNoise(voltage, bufSize);
  }


  public boolean IsSupportNoiseDetect() {
    if (this.m_reader == null)
    {
      return false;
    }
    return this.m_reader.IsSupportNoiseDetect();
  }


  public int RFTransmitterOperate(byte opt, byte ant) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.RFTransmitterOperate(opt, ant);
  }
  public int DetectAntennaCount(int[] mCount) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.DetectAntennaCount(mCount);
  }
  public int DetectAntenna(byte option, int AntennaCount, byte[] AntennaID, byte[] rst, byte[] sta, int[] imp, int[] swr) {
    if (this.m_reader == null)
    {
      return -3;
    }
    return this.m_reader.DetectAntenna(option, AntennaCount, AntennaID, rst, sta, imp, swr);
  }

}
